package com.freestyle.multidatasource;

import com.freestyle.multidatasource.annotation.TargetDataSource;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Method;

/**
 * Created by rocklee on 2020/8/27 10:07
 */
@Aspect
@Order(0)
@Component
public class DataSourceAspect {
  private Logger logger = LoggerFactory.getLogger(DataSourceAspect.class);

  @Before("@annotation(targetDataSource)")
  public void changeDataSource(JoinPoint point, TargetDataSource targetDataSource) throws Throwable {
    String ds = targetDataSource.value();
    setDataSource(ds,point.getSignature());

  }
  private void setDataSource(String ds, Signature st){
    if (!DataSourceContextHolder.containsDataSource(ds)) {
      logger.info("数据源(" + ds + ")不存在-" +st);
    } else {
      logger.info("使用数据源(" + ds + ")-" + st);
      DataSourceContextHolder.changeDataSource(ds);
    }
  }
  private void resetDataSource(Signature st){
    logger.info("恢复数据源-" + st);
    DataSourceContextHolder.clearDataSource();
  }
  @After("@annotation(targetDataSource)")
  public void restoreDataSource(JoinPoint point, TargetDataSource targetDataSource) {
    resetDataSource(point.getSignature());
  }
 /*@Before("@annotation(transactional)")
  public void interceptorTransactional(JoinPoint pj,Transactional transactional) throws Throwable {
    MethodSignature signature = (MethodSignature) pj.getSignature();
    Method method = signature.getMethod();
    TargetDataSource targetDataSource= method.getAnnotation(TargetDataSource.class);
    boolean flag=false;
    if (!StringUtils.isBlank(targetDataSource.value())) {
      flag=true;
      String ds = targetDataSource.value();
      setDataSource(ds,signature);
    }
  }*/
  /*@Around("execution(public * org.springframework.transaction.interceptor.TransactionInterceptor.invoke(..))")
  public void interceptorInvoke(ProceedingJoinPoint pj) throws Throwable {
    MethodSignature signature = (MethodSignature) pj.getSignature();
    Method method = signature.getMethod();
    TargetDataSource targetDataSource= method.getAnnotation(TargetDataSource.class);
    boolean flag=false;
    if (!StringUtils.isBlank(targetDataSource.value())) {
        flag=true;
        String ds = targetDataSource.value();
        setDataSource(ds,signature);
    }
    pj.proceed();
    if (flag){
      resetDataSource(signature);
    }
  }*/

}